<template>
  <el-card class="dr-task" body-class="task-card" shadow="never">
    <template #header>
      模型任务
      <!-- TODO @fan：看看，怎么优化下这个样子哈。 -->
      <el-button @click="handleViewPublic">模型作品</el-button>
    </template>
    <!-- 3D模型列表 -->
    <div class="task-threed-list" ref="threedListRef">
      <ThreedCard
        v-for="threed in threedList"
        :key="threed.id"
        :detail="threed"
        @on-btn-click="handleThreedButtonClick"
      />
    </div>
    <div class="task-threed-pagination">
      <Pagination
        :total="pageTotal"
        v-model:page="queryParams.pageNo"
        v-model:limit="queryParams.pageSize"
        @pagination="getThreedList"
      />
    </div>
  </el-card>

  <!-- 3D模型详情 -->
  <ThreedDetail
    :show="isShowThreedDetail"
    :id="showThreedDetailId"
    @handleDetailClose="handleDetailClose"
    @handle-drawer-close="handleDetailClose"
  />

  <el-dialog
    title="3D模型查看"
    v-model="showDialog"
    fullscreen
    append-to-body
    destroy-on-close
  >
    <IFrame style="width: 100%;" :style="{height: iframeHeight}" :src="threeSrc"/>

    <template #footer>
      <el-button @click="showDialog = false">取 消</el-button>
    </template>
  </el-dialog>

</template>
<script setup lang="ts">
import {
  ThreedApi,
  ThreedVO,
} from '@/api/ai/threed'
import ThreedDetail from './ThreedDetail.vue'
import ThreedCard from './ThreedCard.vue'
import { ElLoading, LoadingOptionsResolved } from 'element-plus'
import { AiThreedStatusEnum } from '@/views/ai/utils/constants'
import download from '@/utils/download'

const message = useMessage() // 消息弹窗
const router = useRouter() // 路由

// 3D模型分页相关的参数
let queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  platform: undefined,
})
const pageTotal = ref<number>(0) // page size
const threedList = ref<ThreedVO[]>([]) // threed 列表
const threedListLoadingInstance = ref<any>() // threed 列表是否正在加载中
const threedListRef = ref<any>() // ref
// 3D模型轮询相关的参数（正在生成中的）
const inProgressThreedMap = ref<{}>({}) // 监听的 threed 映射，一般是生成中（需要轮询），key 为 threed 编号，value 为 threed
const inProgressTimer = ref<any>() // 生成中的 threed 定时器，轮询生成进展
// 3D模型详情相关的参数
const isShowThreedDetail = ref<boolean>(false) // 3D模型详情是否展示
const showThreedDetailId = ref<number>(0) // 3D模型详情的3D模型编号

const threeUrl = import.meta.env.VITE_3D_URL;
const threeSrc = ref(''); //模型浏览
const showDialog = ref(false)
const iframeHeight = ref(window.innerHeight);

/** 处理查看绘图作品 */
const handleViewPublic = () => {
  router.push({
    name: 'AiThreedSquare'
  })
}

/** 查看3D模型的详情  */
const handleDetailOpen = async () => {
  isShowThreedDetail.value = true
}

/** 关闭3D模型的详情  */
const handleDetailClose = async () => {
  isShowThreedDetail.value = false
}

/** 获得 threed 3D模型列表 */
const getThreedList = async () => {
  try {
    // 1. 加载3D模型列表
    threedListLoadingInstance.value = ElLoading.service({
      target: threedListRef.value,
      text: '加载中...'
    } as LoadingOptionsResolved)
    //所属平台
    queryParams = Object.assign(queryParams, {
      platform: props.platform
    });
    const { list, total } = await ThreedApi.getThreedPage(queryParams)
    threedList.value = list
    pageTotal.value = total

    // 2. 计算需要轮询的3D模型
    const newWatThreeds = {}
    threedList.value.forEach((item) => {
      if (item.status === AiThreedStatusEnum.IN_PROGRESS) {
        newWatThreeds[item.id] = item
      }
    })
    inProgressThreedMap.value = newWatThreeds
  } finally {
    // 关闭正在“加载中”的 Loading
    if (threedListLoadingInstance.value) {
      threedListLoadingInstance.value.close()
      threedListLoadingInstance.value = null
    }
  }
}

/** 轮询生成中的 threed 列表 */
const refreshWatchThreeds = async () => {
  const threedIds = Object.keys(inProgressThreedMap.value).map(Number)
  if (threedIds.length == 0) {
    return
  }
  const list = (await ThreedApi.getThreedListMyByIds(threedIds)) as ThreedVO[]
  const newWatchThreeds = {}
  list.forEach((threed) => {
    if (threed.status === AiThreedStatusEnum.IN_PROGRESS) {
      newWatchThreeds[threed.id] = threed
    } else {
      const index = threedList.value.findIndex((oldThreed) => threed.id === oldThreed.id)
      if (index >= 0) {
        // 更新 threedList
        threedList.value[index] = threed
      }
    }
  })
  inProgressThreedMap.value = newWatchThreeds
}

/** 3D模型的点击事件 */
const handleThreedButtonClick = async (type: string, threedDetail: ThreedVO) => {
  // 详情
  if (type === 'more') {
    showThreedDetailId.value = threedDetail.id
    await handleDetailOpen()
    return
  }
  // 删除
  if (type === 'delete') {
    await message.confirm(`是否删除模型?`)
    await ThreedApi.deleteThreed(threedDetail.id)
    await getThreedList()
    message.success('删除成功!')
    return
  }
  // 下载
  if (type === 'download') {
    const url = threedDetail.modelUrl;
    // 使用URL对象解析网址（适用于绝对URL）
    const parsedUrl = new URL(url);
    // 获取文件名，剥离路径
    const filename = parsedUrl.pathname.split('/').pop(); // 得到 'file.txt'
    if(filename){
      await download.downloadUrl(url, filename);
    }
    return
  }
  // 重新生成
  if (type === 'regeneration') {
    await emits('onRegeneration', threedDetail)
    return
  }
  //模型纹理
  if(type === 'texture'){
    await emits('onTexture', threedDetail)
    return;
  }
  //模型精炼
  if(type === 'refine'){
    await emits('onRefine', threedDetail)
    return;
  }
  //模型rig动画
  if(type === 'animationRig'){
    await emits('onAnimationRig', threedDetail)
    return;
  }
  //模型rigretarget动画
  if(type === 'animationRigRetarget'){
    await emits('onAnimationRigRetarget', threedDetail)
    return;
  }
  //预览模型
  if(type === 'open'){
    const detail = await ThreedApi.getThreed(threedDetail.id)
    if(detail.modelIds && detail.modelIds.length){
      threeSrc.value = threeUrl + "/view?id=" + detail.modelIds[0];
    }
    showDialog.value = true
    return;
  }

}

// 定义属性
const props = defineProps({
  platform: {
    type: String,
    required: true,
    default: ''
  },
});

defineExpose({ getThreedList }) // 暴露组件方法

const emits = defineEmits(['onRegeneration', 'onOpen', 'onTexture',
  'onRefine', 'onAnimationRig', 'onAnimationRigRetarget'])

/** 组件挂在的时候 */
onMounted(async () => {
  // 获取 threed 列表
  await getThreedList()
  // 自动刷新 threed 列表
  inProgressTimer.value = setInterval(async () => {
    await refreshWatchThreeds()
  }, 1000 * 3)
})

/** 组件取消挂在的时候 */
onUnmounted(async () => {
  if (inProgressTimer.value) {
    clearInterval(inProgressTimer.value)
  }
})
</script>
<style lang="scss">
.dr-task {
  width: 100%;
  height: 100%;
}
.task-card {
  margin: 0;
  padding: 0;
  height: 100%;
  position: relative;
}

.task-threed-list {
  position: relative;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 100%;
  overflow: auto;
  padding: 20px 20px 140px;
  box-sizing: border-box; /* 确保内边距不会增加高度 */

  > div {
    margin-right: 20px;
    margin-bottom: 20px;
  }
  > div:last-of-type {
    //margin-bottom: 100px;
  }
}

.task-threed-pagination {
  position: absolute;
  bottom: 60px;
  height: 50px;
  line-height: 90px;
  width: 100%;
  z-index: 999;
  background-color: #ffffff;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
</style>
